package cn.kt.ipcount.chatgpt;

import cn.kt.ipcount.chatgpt.domain.ChatgptInfo;
import cn.kt.ipcount.chatgpt.service.ChatgptService;
import cn.kt.ipcount.domain.IpInfo;
import cn.kt.ipcount.domain.vo.IpDataVo;
import cn.kt.ipcount.domain.vo.ResultVO;
import cn.kt.ipcount.utils.IPUtil;
import cn.kt.ipcount.utils.OkHttpClientUtil;
import com.google.gson.Gson;
import com.netflix.hystrix.contrib.javanica.annotation.HystrixCommand;
import com.netflix.hystrix.contrib.javanica.annotation.HystrixProperty;
import lombok.extern.slf4j.Slf4j;
import nl.bitwalker.useragentutils.UserAgent;
import okhttp3.Response;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController;

import javax.servlet.http.HttpServletRequest;
import java.io.IOException;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;

/**
 * Created by tao.
 * Date: 2023/2/9 15:58
 * 描述:
 */
@RestController
@Slf4j
public class ChatGptController {

    private static final String GET_IPDATA_URL = "https://restapi.amap.com/v5/ip?key=0347f57731f46576ad6182573193f16f&type=4&ip=";
    private static final int ONLINE_STATUS_UP = 1;
    private static final int ONLINE_STATUS_DOWN = 0;

    @Autowired
    private ChatgptService chatgptService;

    /*
     * ChatGpt聊天
     */
    @GetMapping("/api/chat/send")
    @HystrixCommand(fallbackMethod = "timeOutHandler",
            commandProperties = {
                    @HystrixProperty(name = "execution.isolation.strategy", value = "THREAD"),
                    @HystrixProperty(name = "execution.isolation.thread.timeoutInMilliseconds", value = "60000"),
                    @HystrixProperty(name = "circuitBreaker.enabled", value = "true"),
                    @HystrixProperty(name = "circuitBreaker.requestVolumeThreshold", value = "2")}
    )
    public ResultVO chatGpt(String prompt, HttpServletRequest req) throws IOException {
        log.info("【prompt内容】：{}", prompt);
        if (!StringUtils.hasLength(prompt.trim())) {
            return new ResultVO(211, "请输入聊天内容");
        }
        Object result = ChatGptUtil.ChatGptSend(prompt);

        // 记录内容和ip信息等
        UserAgent userAgent = UserAgent.parseUserAgentString(req.getHeader("user-agent"));
        String browserName = userAgent.getBrowser().getName();
        String os = userAgent.getOperatingSystem().getName();
        String ip = IPUtil.getIpAddress(req);
        String ua = browserName + " " + os;

        // 获取相关信息
        String url = GET_IPDATA_URL + ip;
        Response response = OkHttpClientUtil.getData(url);
        String json = new String(response.body().bytes());
        Gson gson = new Gson();
        IpDataVo ipData = gson.fromJson(json, IpDataVo.class);
        String address = ipData.getCountry() + " " + ipData.getProvince() + " " + ipData.getCity() + " " + ipData.getDistrict();
        ChatgptInfo chatgptInfo = new ChatgptInfo(prompt, result.toString(), ip, address, ua, new Date(), ipData.getLocation());
        chatgptService.save(chatgptInfo);

        return new ResultVO(200, "ok", result);
    }

    //用来善后的方法
    public ResultVO timeOutHandler(String prompt, HttpServletRequest req) {
        return new ResultVO(212, "服务器繁忙或者运行报错，请稍后再试");
    }

    /*
     * 获取历史访问的总数居
     */
    @GetMapping("/api/chat/total")
    @ResponseBody
    public ResultVO getTotal() {
        List<ChatgptInfo> chatgptInfos = chatgptService.queryAll();
        return new ResultVO(200, "OK", chatgptInfos);
    }


    /*
     * 获取前1000条总数据
     */
    @GetMapping("/api/chat/limit")
    @ResponseBody
    public ResultVO getLimit() {
        Pageable pageable = PageRequest.of(0, 1000);
        List<ChatgptInfo> chatgptInfos = chatgptService.findAllByOrderByIdDesc(pageable);
        return new ResultVO(200, "OK", chatgptInfos);
    }
}